﻿#pragma once

#include "ddcl.h"
#include "ddclsocketpoll.h"
#include "ddclservice.h"

#ifndef DD_WINDOWS
#include <arpa/inet.h>
#endif

enum{
    DDCL_SOCKET_CONNECT = 0,
    DDCL_SOCKET_ACCEPT,
    DDCL_SOCKET_READ,
    DDCL_SOCKET_ERROR,
};

enum {
    DDCL_SOCKET_IPV0,
    DDCL_SOCKET_IPV4,
    DDCL_SOCKET_IPV6,
};

enum {
    DDCL_SOCKET_TCP,
    DDCL_SOCKET_UDP,
};

typedef union tag_ddcl_SocketAddr{
    struct sockaddr s;
    struct sockaddr_in v4;
    struct sockaddr_in6 v6;
}ddcl_SocketAddr;

typedef struct tag_ddcl_SocketInfo{
    char ip[128];
    dduint16 port;
    int protocol;
    int family;
}ddcl_SocketInfo;

typedef ddcl_Handle ddcl_Socket;

DDCLAPI int
ddcl_open_socket_module ();

DDCLAPI void
ddcl_close_socket_module ();

DDCLAPI ddcl_Socket
ddcl_bind_socket (const char * host, dduint16 port,
        int protocol, int family);


DDCLAPI ddcl_Socket
ddcl_connect_socket (ddcl_Service from,
        const char * host, dduint16 port,
        ddcl_Session session);


DDCLAPI int
ddcl_listen_socket (ddcl_Service from,
        ddcl_Session * session, ddcl_Socket fd, int backlog);

DDCLAPI int
ddcl_accept_socket (ddcl_Socket fd,
        ddcl_Service from, ddcl_Session * session);

DDCLAPI int
ddcl_read_socket(ddcl_Socket fd,
        ddcl_Service from, size_t sz,
        ddcl_Session * session);

DDCLAPI int
ddcl_send_socket(ddcl_Socket fd,
        ddcl_Service from, const void * buf, size_t sz);

DDCLAPI int
ddcl_close_socket(ddcl_Socket fd, ddcl_Service from);

DDCLAPI dduint32
ddcl_getall_socket_count();

DDCLAPI int
ddcl_forward_socket (ddcl_Socket fd,
        ddcl_Service from, ddcl_Session * session);
